package com.hzy.fivepalace.common.config;

import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.hzy.fivepalace.common.exception.AppException;
import com.hzy.fivepalace.common.exception.NoLoginException;
import com.hzy.fivepalace.common.exception.WxPayCallbackException;
import com.hzy.fivepalace.common.util.ResponseUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ConstraintViolationException;

/**
 * 全局异常处理配置
 */
@Slf4j
@ResponseBody
@ControllerAdvice
public class ExceptionConfig {

    @Value("${spring.servlet.multipart.max-file-size}")
    private String maxFileSize;

    @Value("${spring.servlet.multipart.max-request-size}")
    private String maxRequestSize;

    /**
     * 全局捕捉异常情况，避免直接报错给前台
     *
     * @param request
     * @param exception
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public Object exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception exception) {
        //必填参数异常
        if (exception instanceof MissingServletRequestParameterException) {
            return ResponseUtil.fail("参数 '" + ((MissingServletRequestParameterException) exception).getParameterName() + "' 不正确");
        }
        if (exception instanceof ConstraintViolationException) {
            return ResponseUtil.fail(((ConstraintViolationException) exception).getConstraintViolations().stream().findFirst().get().getMessage());
        }

        //自定义微信回调异常
        if (exception instanceof WxPayCallbackException) {
            return WxPayNotifyResponse.fail(exception.getMessage());
        }

        if (exception instanceof AppException) {
            return ResponseUtil.fail(exception.getMessage());
        }

        if (exception instanceof NoLoginException) {
            return ResponseUtil.unlogin();
        }


        //请求方法异常
        if (exception instanceof HttpRequestMethodNotSupportedException) {
            return ResponseUtil.fail(String.format("该路径不支持%s请求", request.getMethod()));
        }
        if (exception instanceof MissingServletRequestParameterException) {
            return ResponseUtil.fail(String.format("参数【%s】为空", ((MissingServletRequestParameterException) exception).getParameterName()));
        }

        log.error("请求路径：系统异常,MSG:", request.getRequestURI(), exception);

        return ResponseUtil.fail("系统错误,请联系管理员");
    }


    @ExceptionHandler(value = MultipartException.class)
    public Object fileUploadException(MultipartException e, HttpServletRequest request) {
        String errorMsg = e.getCause().getCause().toString();
        if (StringUtils.contains(errorMsg, "FileUploadBase$FileSizeLimitExceededException")) {
            //单个文件大小超出限制抛出的异常
            log.error("请求路径：{}, 文件上传异常:{}", request.getRequestURI(), "单个文件大小不能超过" + maxFileSize);
            return ResponseUtil.fail("单个上传文件大小不能超过" + maxFileSize);
        } else if (StringUtils.contains(errorMsg, "FileUploadBase$SizeLimitExceededException")) {
            //总文件大小超出限制抛出的异常
            log.error("请求路径：{}, 文件上传异常:{}", request.getRequestURI(), "总文件大小不能超过" + maxRequestSize);
            return ResponseUtil.fail("总文件大小不能超过" + maxRequestSize);
        }
        log.error("请求路径：{}, 文件上传异常:{}", request.getRequestURI(), errorMsg);
        return ResponseUtil.fail("系统错误,文件上传异常");
    }

}
